<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="generator" content="Docusaurus v2.0.0-alpha.65">
<title data-react-helmet="true">3. 应用启动 | Fur</title><meta data-react-helmet="true" name="docsearch:version" content="current,latest"><meta data-react-helmet="true" name="twitter:card" content="summary_large_image"><meta data-react-helmet="true" property="og:title" content="3. 应用启动 | Fur"><meta data-react-helmet="true" name="description" content="3.1 Startup 类"><meta data-react-helmet="true" property="og:description" content="3.1 Startup 类"><meta data-react-helmet="true" property="og:url" content="https://furos.cn/docs/appstartup"><link data-react-helmet="true" rel="shortcut icon" href="/img/favicon.ico"><link data-react-helmet="true" rel="canonical" href="https://furos.cn/docs/appstartup"><link rel="stylesheet" href="/styles.8aef5b7b.css">
<link rel="preload" href="/styles.8352e18a.js" as="script">
<link rel="preload" href="/runtime~main.98e14d7d.js" as="script">
<link rel="preload" href="/main.04e1b7d6.js" as="script">
<link rel="preload" href="/1.72c59440.js" as="script">
<link rel="preload" href="/2.a2e0b0a9.js" as="script">
<link rel="preload" href="/3.054f69af.js" as="script">
<link rel="preload" href="/1be78505.da78ff7d.js" as="script">
<link rel="preload" href="/85.0018927c.js" as="script">
<link rel="preload" href="/f976f453.e1be0e0e.js" as="script">
<link rel="preload" href="/17896441.9aece880.js" as="script">
<link rel="preload" href="/5ce0ebbd.9ae366a6.js" as="script">
</head>
<body>
<script>!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){var t=null;try{t=localStorage.getItem("theme")}catch(t){}return t}();t(null!==e?e:"light")}()</script><div id="__docusaurus">
<nav class="navbar navbar--fixed-top"><div class="navbar__inner"><div class="navbar__items"><div aria-label="Navigation bar toggle" class="navbar__toggle" role="button" tabindex="0"><svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30" role="img" focusable="false"><title>Menu</title><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></div><a class="navbar__brand" href="/"><img class="navbar__logo" src="/img/logo.png" alt="Fur Logo"><strong class="navbar__title">Fur</strong></a><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="/docs/">Next</a><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="/docs">文档</a><a class="navbar__item navbar__link" href="/blog">博客</a><a href="https://chinadot.net" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">社区</a></div><div class="navbar__items navbar__items--right"><a href="https://space.bilibili.com/695987967" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">视频</a><div class="navbar__item dropdown dropdown--hoverable dropdown--right"><a target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">工具</a><ul class="dropdown__menu"><li><a target="_blank" rel="noopener noreferrer" class="dropdown__link" position="left">代码生成器</a></li></ul></div><a href="https://gitee.com/monksoul/Fur/board" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">看板</a><div class="navbar__item dropdown dropdown--hoverable dropdown--right"><a target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">仓库</a><ul class="dropdown__menu"><li><a href="https://gitee.com/monksoul/Fur" target="_blank" rel="noopener noreferrer" class="dropdown__link" position="left">Gitee</a></li><li><a href="https://github.com/MonkSoul/Fur" target="_blank" rel="noopener noreferrer" class="dropdown__link" position="left">GitHub</a></li></ul></div><div class="react-toggle react-toggle--disabled displayOnlyInLargeViewport_2aTZ"><div class="react-toggle-track"><div class="react-toggle-track-check"><span class="toggle_BsTx">🌜</span></div><div class="react-toggle-track-x"><span class="toggle_BsTx">🌞</span></div></div><div class="react-toggle-thumb"></div><input type="checkbox" disabled="" aria-label="Dark mode toggle" class="react-toggle-screenreader-only"></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div><div class="navbar-sidebar"><div class="navbar-sidebar__brand"><a class="navbar__brand" href="/"><img class="navbar__logo" src="/img/logo.png" alt="Fur Logo"><strong class="navbar__title">Fur</strong></a></div><div class="navbar-sidebar__items"><div class="menu"><ul class="menu__list"><li class="menu__list-item"><a target="_blank" rel="noopener noreferrer" class="menu__link">Versions</a></li><li class="menu__list-item"><a aria-current="page" class="menu__link navbar__link--active" href="/docs">文档</a></li><li class="menu__list-item"><a class="menu__link" href="/blog">博客</a></li><li class="menu__list-item"><a href="https://chinadot.net" target="_blank" rel="noopener noreferrer" class="menu__link">社区</a></li><li class="menu__list-item"><a href="https://space.bilibili.com/695987967" target="_blank" rel="noopener noreferrer" class="menu__link">视频</a></li><li class="menu__list-item"><a target="_blank" rel="noopener noreferrer" class="menu__link menu__link--sublist">工具</a><ul class="menu__list"><li class="menu__list-item"><a target="_blank" rel="noopener noreferrer" class="menu__link" position="left">代码生成器</a></li></ul></li><li class="menu__list-item"><a href="https://gitee.com/monksoul/Fur/board" target="_blank" rel="noopener noreferrer" class="menu__link">看板</a></li><li class="menu__list-item"><a target="_blank" rel="noopener noreferrer" class="menu__link menu__link--sublist">仓库</a><ul class="menu__list"><li class="menu__list-item"><a href="https://gitee.com/monksoul/Fur" target="_blank" rel="noopener noreferrer" class="menu__link" position="left">Gitee</a></li><li class="menu__list-item"><a href="https://github.com/MonkSoul/Fur" target="_blank" rel="noopener noreferrer" class="menu__link" position="left">GitHub</a></li></ul></li></ul></div></div></div></nav><div class="main-wrapper"><div class="docPage_2gpo"><div class="docSidebarContainer_3_JD" role="complementary"><div class="sidebar_2urC"><div class="menu menu--responsive menu_5FrY"><button aria-label="Open Menu" aria-haspopup="true" class="button button--secondary button--sm menu__button" type="button"><svg aria-label="Menu" class="sidebarMenuIcon_Dm3K" xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 32 32" role="img" focusable="false"><title>Menu</title><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><ul class="menu__list"><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">1. 框架介绍</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/">1.1 介绍</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/author">1.2 关于作者</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/source">1.3 源码结构</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/reference">1.4 项目引用</a></li></ul></li><li class="menu__list-item"><a class="menu__link" href="/docs/get-start">2. 一分钟入门</a></li><li class="menu__list-item"><a aria-current="page" class="menu__link menu__link--active active" href="/docs/appstartup">3. 应用启动</a></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">4. 配置与选项</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/configuration">4.1 配置</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/options">4.2 选项</a></li></ul></li><li class="menu__list-item"><a class="menu__link" href="/docs/dynamic-api-controller">5. 动态 WebAPI</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/specification-document">6. 规范化接口文档</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/friendly-exception">7. 友好异常处理</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/data-validation">8. 数据校验</a></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">9. 数据库操作指南</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext">9.1 数据库上下文</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-locator">9.2 数据库上下文定位器</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/entity">9.3 数据库实体</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-repository">9.4 仓储模式</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-add">9.5 新增操作</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-update">9.6 更新操作</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-add-or-update">9.7 新增或更新操作</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-delete">9.8 删除操作</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-batch">9.9 批量操作</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-query">9.10 查询操作</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-hight-query">9.11 高级查询操作</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-view">9.12 视图操作</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-proc">9.13 存储过程操作</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-function">9.14 函数操作</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-sql">9.15 Sql 操作</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-sql-template">9.16 Sql 模板</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-sql-proxy">9.17 Sql 高级代理</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-multi-database">9.18 多数据库操作</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-db-first">9.19 数据库生成模型</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-code-first">9.20 模型生成数据库</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-seed-data">9.21 实体种子数据</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-audit">9.22 审计日志</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-filter">9.23 实体/全局查询筛选器</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-Interceptor">9.24 数据库操作拦截器</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/tran">9.25 事务和工作单元</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/dbcontext-read-write">9.26 读写分离/主从复制</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/split-db">9.27 分表分库</a></li></ul></li><li class="menu__list-item"><a class="menu__link" href="/docs/saas">10. SaaS 多租户</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/dependency-injection">11. 依赖注入/控制反转</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/object-mapper">12. 对象数据映射</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/cache">13. 分布式缓存</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/auth-control">14. 安全鉴权</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/cors">15. CORS 跨域</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/view-engine">16. 视图引擎</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/local-language">17. 多语言处理</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/event-bus">18. 事件总线</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/logging">19. 日志记录</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/http">20. 网络请求</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/process-service">21. 进程服务</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/job">22. 任务调度</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/signalr">23. 即时通讯</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/grpc">24. Grpc 服务</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/deploy">25. 托管部署</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/devops">26. 持续部署集成</a></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">27. 测试指南</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/unittest">27.1 单元测试</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/performance">27.2 性能测试</a></li></ul></li><li class="menu__list-item"><a class="menu__link" href="/docs/contribute">28. 贡献指南</a></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">29. 常见问题</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/answer">29.1 常见问题</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/errors">29.2 常见错误</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/gooduse">29.3 最佳实践</a></li></ul></li></ul></div></div></div><main class="docMainContainer_3EyW"><div class="container padding-vert--lg docItemWrapper_1EkI"><div class="row"><div class="col docItemCol_2ASc"><div class="docItemContainer_3QWW"><article><header><h1 class="docTitle_1Lrw">3. 应用启动</h1></header><div class="markdown"><h2><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2cZh" id="31-startup-类"></a>3.1 <code>Startup</code> 类<a aria-hidden="true" tabindex="-1" class="hash-link" href="#31-startup-类" title="Direct link to heading">#</a></h2><p><code>Startup</code> 类是 <code>ASP.NET Core</code> 应用程序启动默认调用的类，该类是在 <code>Program.cs</code> 中配置：</p><div class="mdxCodeBlock_1XEh"><div style="color:#bfc7d5;background-color:#292d3e" class="codeBlockTitle_3nn1">Fur.Web.Entry\Program.cs</div><div class="codeBlockContent_1u-d"><button type="button" aria-label="Copy code to clipboard" class="copyButton_10dd undefined">Copy</button><div tabindex="0" class="prism-code language-cs codeBlock_3iAC codeBlockWithTitle_3QsD"><div class="codeBlockLines_b7E3" style="color:#bfc7d5;background-color:#292d3e"><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Microsoft.AspNetCore.Hosting;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Microsoft.Extensions.Hosting;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">namespace Fur.Web.Entry</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">{</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    public class Program</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        public static void Main(string[] args)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            CreateHostBuilder(args).Build().Run();</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        public static IHostBuilder CreateHostBuilder(string[] args)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            return Host.CreateDefaultBuilder(args)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                .ConfigureWebHostDefaults(webBuilder =&gt;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                    webBuilder.Inject()</span></div><div class="token-line docusaurus-highlight-code-line" style="color:#bfc7d5"><span class="token plain">                        .UseStartup&lt;Startup&gt;();</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                });</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">}</span></div></div></div></div></div><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2cZh" id="311-startup-两个重要方法"></a>3.1.1 <code>Startup</code> 两个重要方法<a aria-hidden="true" tabindex="-1" class="hash-link" href="#311-startup-两个重要方法" title="Direct link to heading">#</a></h3><p><code>Startup</code> 默认有两个重要的方法:</p><ul><li><code>ConfigureServices</code>：配置应用所需服务，在该方法中可以添加应用所需要的功能或服务</li><li><code>Configure</code>：配置应用请求处理管道</li></ul><p>默认代码如下：</p><div class="mdxCodeBlock_1XEh"><div style="color:#bfc7d5;background-color:#292d3e" class="codeBlockTitle_3nn1">Fur.Web.Entry\Startup.cs</div><div class="codeBlockContent_1u-d"><button type="button" aria-label="Copy code to clipboard" class="copyButton_10dd undefined">Copy</button><div tabindex="0" class="prism-code language-cs codeBlock_3iAC codeBlockWithTitle_3QsD"><div class="codeBlockLines_b7E3" style="color:#bfc7d5;background-color:#292d3e"><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Microsoft.AspNetCore.Builder;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Microsoft.AspNetCore.Hosting;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Microsoft.Extensions.DependencyInjection;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">namespace Fur.Web.Entry</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">{</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    public class Startup</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    {</span></div><div class="token-line docusaurus-highlight-code-line" style="color:#bfc7d5"><span class="token plain">        public void ConfigureServices(IServiceCollection services)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line docusaurus-highlight-code-line" style="color:#bfc7d5"><span class="token plain">        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">}</span></div></div></div></div></div><p>在这里，不打算详细讲 <code>Startup</code> 类的具体功能和作用。</p><div class="admonition admonition-note alert alert--secondary"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>了解更多</h5></div><div class="admonition-content"><p>想了解更多 <code>Startup</code> 知识可查阅 <a href="https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/startup?view=aspnetcore-3.1" target="_blank" rel="noopener noreferrer">ASP.NET Core - Startup 类</a> 章节。</p></div></div><h2><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2cZh" id="32-appstartup"></a>3.2 <code>AppStartup</code><a aria-hidden="true" tabindex="-1" class="hash-link" href="#32-appstartup" title="Direct link to heading">#</a></h2><p>在 <code>Fur</code> 框架中，提供了更为灵活的 <code>Startup</code> 类配置方式，无需在 <code>Web 启用层</code> 中配置，可将配置放到任何项目层。</p><p>可能会有读者有疑问，为什么要多此一举呢？原因有几点：</p><ul><li><code>Startup</code> 类默认和 <code>Web 应用层</code> 绑定在一起，这样就会导致如果我创建了新的 <code>Web 应用层</code>，<code>Startup</code> 又要重新配置</li><li>随着业务的增长，需要集成越来越多的第三方服务，这时候 <code>Startup</code> 类就会变得越来越臃肿，难以维护</li><li><code>Startup</code> 类无法与其他项目类型进行共用</li></ul><p>所以，<code>Fur</code> 提供了更加灵活的配置方式：<code>AppStartup</code>。</p><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2cZh" id="321-如何配置-appstartup"></a>3.2.1 如何配置 <code>AppStartup</code><a aria-hidden="true" tabindex="-1" class="hash-link" href="#321-如何配置-appstartup" title="Direct link to heading">#</a></h3><p><code>AppStartup</code> 是一个抽象的空类，没有任何定义成员。正是因为这样，才提供更加灵活的配置方式。</p><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2cZh" id="322-appstartup-约定"></a>3.2.2 <code>AppStartup</code> 约定<a aria-hidden="true" tabindex="-1" class="hash-link" href="#322-appstartup-约定" title="Direct link to heading">#</a></h3><p><code>AppStartup</code> 派生类只有两个小约定：</p><ul><li>任何公开、非静态、返回值为 <code>void</code> 且方法第一个参数是 <code>IServiceCollection</code> 类型，那么他就是一个 <code>ConfigureServices</code> 方法</li><li>任何公开、非静态、返回值为 <code>void</code> 且方法第一个参数是 <code>IApplicationBuilder</code> 类型，第二个参数是 <code>IWebHostEnvironment</code> 类型，那么他就是一个 <code>Configure</code> 方法</li></ul><p>所以，我们可以自由的编写方法，只要遵循约定即可，如：</p><div class="mdxCodeBlock_1XEh"><div class="codeBlockContent_1u-d"><button type="button" aria-label="Copy code to clipboard" class="copyButton_10dd">Copy</button><div tabindex="0" class="prism-code language-cs codeBlock_3iAC"><div class="codeBlockLines_b7E3" style="color:#bfc7d5;background-color:#292d3e"><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Microsoft.Extensions.DependencyInjection;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">namespace Fur.EntityFramework.Core</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">{</span></div><div class="token-line docusaurus-highlight-code-line" style="color:#bfc7d5"><span class="token plain">    public class MyStartup : AppStartup</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    {</span></div><div class="token-line docusaurus-highlight-code-line" style="color:#bfc7d5"><span class="token plain">        public void ConfigureServices(IServiceCollection services)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            services.AddDataValidation();</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line docusaurus-highlight-code-line" style="color:#bfc7d5"><span class="token plain">        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            app.UseSwagger();</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        // 可以随意定义名字和方法</span></div><div class="token-line docusaurus-highlight-code-line" style="color:#bfc7d5"><span class="token plain">        public void XXXXName(IServiceCollection services)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        // 可以随意定义名字和方法</span></div><div class="token-line docusaurus-highlight-code-line" style="color:#bfc7d5"><span class="token plain">        public void ZZZName(IApplicationBuilder app, IWebHostEnvironment env)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">}</span></div></div></div></div></div><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2cZh" id="323-appstartup-配置顺序"></a>3.2.3 <code>AppStartup</code> 配置顺序<a aria-hidden="true" tabindex="-1" class="hash-link" href="#323-appstartup-配置顺序" title="Direct link to heading">#</a></h3><p>默认情况下，<code>AppStartup</code> 配置顺序由所在程序集的名称进行正序调用，如果我们需要配置执行顺序，只需要在 <code>AppStartup</code> 派生类中贴 <code>[AppStartup(order)]</code> 特性即可。</p><p><code>order</code> 数值越大，越在前面调用，如：</p><div class="mdxCodeBlock_1XEh"><div class="codeBlockContent_1u-d"><button type="button" aria-label="Copy code to clipboard" class="copyButton_10dd">Copy</button><div tabindex="0" class="prism-code language-cs codeBlock_3iAC"><div class="codeBlockLines_b7E3" style="color:#bfc7d5;background-color:#292d3e"><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Microsoft.Extensions.DependencyInjection;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">namespace Fur.EntityFramework.Core</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">{</span></div><div class="token-line docusaurus-highlight-code-line" style="color:#bfc7d5"><span class="token plain">    [AppStartup(10)]</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    public class FirstStartup : AppStartup</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        public void ConfigureServices(IServiceCollection services)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">}</span></div></div></div></div></div><div class="mdxCodeBlock_1XEh"><div class="codeBlockContent_1u-d"><button type="button" aria-label="Copy code to clipboard" class="copyButton_10dd">Copy</button><div tabindex="0" class="prism-code language-cs codeBlock_3iAC"><div class="codeBlockLines_b7E3" style="color:#bfc7d5;background-color:#292d3e"><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Microsoft.Extensions.DependencyInjection;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">namespace Fur.EntityFramework.Core</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">{</span></div><div class="token-line docusaurus-highlight-code-line" style="color:#bfc7d5"><span class="token plain">    [AppStartup(9)]</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    public class SecondStartup : AppStartup</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        public void ConfigureServices(IServiceCollection services)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">}</span></div></div></div></div></div><p><code>FirstStartup</code> 会在 <code>SecondStartup</code> 之前调用。</p><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2cZh" id="324-appstartup-方法调用顺序"></a>3.2.4 <code>AppStartup</code> 方法调用顺序<a aria-hidden="true" tabindex="-1" class="hash-link" href="#324-appstartup-方法调用顺序" title="Direct link to heading">#</a></h3><p><code>AppStartup</code> 方法调用顺序和方法的书写先后有关，越在前面的方法越先调用。</p><h2><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2cZh" id="33-框架默认-appstartup-实现"></a>3.3 框架默认 <code>AppStartup</code> 实现<a aria-hidden="true" tabindex="-1" class="hash-link" href="#33-框架默认-appstartup-实现" title="Direct link to heading">#</a></h2><p><code>Fur</code> 框架默认在每一个项目层中都创建了一个 <code>AppStartup</code> 派生类，方便大家配置。如：</p><ul><li><code>FurStartup.cs</code>：<code>Fur</code> 框架核心启动类（通常无需配置）</li><li><code>FurApplicationStartup.cs</code>：业务服务启动类</li><li><code>FurCoreStartup.cs</code>：应用核心功能启动类</li><li><code>FurEntityFrameworkCoreStartup.cs</code>：数据库相关启动类</li><li><code>FurWebCoreStartup.cs</code>：<code>Web</code> 核心启动配置类</li></ul><h2><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2cZh" id="34-startup-配置最佳实践"></a>3.4 <code>Startup</code> 配置最佳实践<a aria-hidden="true" tabindex="-1" class="hash-link" href="#34-startup-配置最佳实践" title="Direct link to heading">#</a></h2><p>建议 <code>Web</code> 启动层的 <code>Startup.cs</code> 保持为空方法体，如：</p><div class="mdxCodeBlock_1XEh"><div style="color:#bfc7d5;background-color:#292d3e" class="codeBlockTitle_3nn1">Fur.Web.Entry\Startup.cs</div><div class="codeBlockContent_1u-d"><button type="button" aria-label="Copy code to clipboard" class="copyButton_10dd undefined">Copy</button><div tabindex="0" class="prism-code language-cs codeBlock_3iAC codeBlockWithTitle_3QsD"><div class="codeBlockLines_b7E3" style="color:#bfc7d5;background-color:#292d3e"><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Microsoft.AspNetCore.Builder;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Microsoft.AspNetCore.Hosting;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Microsoft.Extensions.DependencyInjection;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">namespace Fur.Web.Entry</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">{</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    public class Startup</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        public void ConfigureServices(IServiceCollection services)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">}</span></div></div></div></div></div><p>将所有 <code>Web 应用层</code> 配置迁移到 <code>FurWebCoreStartup.cs</code> 中，如：</p><div class="mdxCodeBlock_1XEh"><div style="color:#bfc7d5;background-color:#292d3e" class="codeBlockTitle_3nn1">Fur.Web.Core\FurWebCoreStartup.cs</div><div class="codeBlockContent_1u-d"><button type="button" aria-label="Copy code to clipboard" class="copyButton_10dd undefined">Copy</button><div tabindex="0" class="prism-code language-cs codeBlock_3iAC codeBlockWithTitle_3QsD"><div class="codeBlockLines_b7E3" style="color:#bfc7d5;background-color:#292d3e"><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Fur.UnifyResult;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Microsoft.AspNetCore.Builder;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Microsoft.AspNetCore.Hosting;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Microsoft.Extensions.DependencyInjection;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Microsoft.Extensions.Hosting;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">namespace Fur.Web.Core</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">{</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    [AppStartup(800)]</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    public sealed class FurWebCoreStartup : AppStartup</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        public void ConfigureServices(IServiceCollection services)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            services.AddCorsAccessor();</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            services.AddSpecificationDocuments();</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            services.AddControllers()</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                       .AddDynamicApiControllers()</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                       .AddDataValidation()</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                       .AddFriendlyException()</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                       .AddUnifyResult&lt;RESTfulResult, RESTfulResultProvider&gt;();</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            if (env.IsDevelopment())</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                app.UseDeveloperExceptionPage();</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            app.UseHttpsRedirection();</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            app.UseRouting();</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            app.UseCorsAccessor();</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            app.UseAuthentication();</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            app.UseAuthorization();</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            app.UseSpecificationDocuments();</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            app.UseEndpoints(endpoints =&gt;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                endpoints.MapControllers();</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            });</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">}</span></div></div></div></div></div><p>这样，后续更换 <code>Web 应用层</code> 也无需重新配置 <code>Startup.cs</code></p><h2><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2cZh" id="35-关于-appsettingsjson"></a>3.5 关于 <code>appsettings.json</code><a aria-hidden="true" tabindex="-1" class="hash-link" href="#35-关于-appsettingsjson" title="Direct link to heading">#</a></h2><p>在默认情况下，<code>ASP.NET Core</code> 配置放在 <code>appsettings.json</code> 中配置，但是这样的方式和 <code>Startup.cs</code> 配置一样的道理，一旦我们更换了 <code>Web 应用层</code>，那么 <code>appsettings.json</code> 又要重新配置一次。</p><p>所以，<code>Fur</code> 框架提供了更加灵活的方式配置 <code>appsettings.json</code>，<strong>只需要在任何项目层根目录下创建 <code>.json</code> 文件即可</strong></p><p><strong><code>Fur</code> 框架最后会自动合并所有分散的配置文件。</strong></p><p>如我们在 <code>Fur.EntityFramework.Core</code> 层创建 <code>dbsettings.json</code> 配置数据库连接字符串，如：</p><div class="mdxCodeBlock_1XEh"><div style="color:#bfc7d5;background-color:#292d3e" class="codeBlockTitle_3nn1">Fur.EntityFramework.Core\dbsettings.json</div><div class="codeBlockContent_1u-d"><button type="button" aria-label="Copy code to clipboard" class="copyButton_10dd undefined">Copy</button><div tabindex="0" class="prism-code language-json codeBlock_3iAC codeBlockWithTitle_3QsD"><div class="codeBlockLines_b7E3" style="color:#bfc7d5;background-color:#292d3e"><div class="token-line" style="color:#bfc7d5"><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token property">&quot;ConnectionStrings&quot;</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token property">&quot;DbConnectionString&quot;</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">&quot;Server=localhost;Database=Fur;User=sa;Password=000000;MultipleActiveResultSets=True;&quot;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token property">&quot;Sqlite3ConnectionString&quot;</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">&quot;Data Source=./Fur.db&quot;</span><span class="token plain"></span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span></div></div></div></div></div><p><strong>无需在 <code>appsettings.json</code> 中配置</strong>，下面是 <code>appsettings.json</code> 默认代码:</p><div class="mdxCodeBlock_1XEh"><div class="codeBlockContent_1u-d"><button type="button" aria-label="Copy code to clipboard" class="copyButton_10dd">Copy</button><div tabindex="0" class="prism-code language-json codeBlock_3iAC"><div class="codeBlockLines_b7E3" style="color:#bfc7d5;background-color:#292d3e"><div class="token-line" style="color:#bfc7d5"><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token property">&quot;Logging&quot;</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token property">&quot;LogLevel&quot;</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">      </span><span class="token property">&quot;Default&quot;</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">&quot;Information&quot;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">      </span><span class="token property">&quot;Microsoft&quot;</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">&quot;Warning&quot;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">      </span><span class="token property">&quot;Microsoft.Hosting.Lifetime&quot;</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">&quot;Information&quot;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">      </span><span class="token property">&quot;Microsoft.EntityFrameworkCore&quot;</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">&quot;Information&quot;</span><span class="token plain"></span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token property">&quot;AllowedHosts&quot;</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">&quot;*&quot;</span><span class="token plain"></span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span></div></div></div></div></div><p>这样我们把配置文件分散在不同项目层之后，就可以实现共用和共享了。</p><h2><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2cZh" id="36-神奇的-inject"></a>3.6 神奇的 <code>Inject()</code><a aria-hidden="true" tabindex="-1" class="hash-link" href="#36-神奇的-inject" title="Direct link to heading">#</a></h2><p><code>Inject()</code> 方法是 <code>Fur</code> 框架提供的最小侵入式的方法，可以让任何 <code>ASP.NET Core</code> Web 项目瞬间支持所有 <code>Fur</code> 框架特性。</p><p>我们创建了新的 <code>Web 项目</code>，只需要三个步骤即可：</p><ul><li>添加 <code>Fur.Web.Core</code> 项目引用</li><li>在 <code>Program.cs</code> 中调用即可</li><li>将 <code>Startup.cs</code> 代码迁移到 <code>Fur.Web.Core</code> 项目的 <code>FurWebCoreStartup.cs</code> 中</li></ul><p>如：</p><div class="mdxCodeBlock_1XEh"><div style="color:#bfc7d5;background-color:#292d3e" class="codeBlockTitle_3nn1">Fur.Web.Entry\Program.cs</div><div class="codeBlockContent_1u-d"><button type="button" aria-label="Copy code to clipboard" class="copyButton_10dd undefined">Copy</button><div tabindex="0" class="prism-code language-cs codeBlock_3iAC codeBlockWithTitle_3QsD"><div class="codeBlockLines_b7E3" style="color:#bfc7d5;background-color:#292d3e"><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Microsoft.AspNetCore.Hosting;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Microsoft.Extensions.Hosting;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">namespace Fur.Web.Entry</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">{</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    public class Program</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        public static void Main(string[] args)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            CreateHostBuilder(args).Build().Run();</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        public static IHostBuilder CreateHostBuilder(string[] args)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            return Host.CreateDefaultBuilder(args)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                .ConfigureWebHostDefaults(webBuilder =&gt;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                {</span></div><div class="token-line docusaurus-highlight-code-line" style="color:#bfc7d5"><span class="token plain">                    webBuilder.Inject()</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                        .UseStartup&lt;Startup&gt;();</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                });</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">}</span></div></div></div></div></div><div class="mdxCodeBlock_1XEh"><div style="color:#bfc7d5;background-color:#292d3e" class="codeBlockTitle_3nn1">Fur.Web.Entry\Startup.cs</div><div class="codeBlockContent_1u-d"><button type="button" aria-label="Copy code to clipboard" class="copyButton_10dd undefined">Copy</button><div tabindex="0" class="prism-code language-cs codeBlock_3iAC codeBlockWithTitle_3QsD"><div class="codeBlockLines_b7E3" style="color:#bfc7d5;background-color:#292d3e"><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Microsoft.AspNetCore.Builder;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Microsoft.AspNetCore.Hosting;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">using Microsoft.Extensions.DependencyInjection;</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">namespace Fur.Web.Entry</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">{</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    public class Startup</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        public void ConfigureServices(IServiceCollection services)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        {</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    }</span></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">}</span></div></div></div></div></div><div class="admonition admonition-important alert alert--info"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span><code>Startup.cs</code> 代码迁移</h5></div><div class="admonition-content"><p>只需要将 <code>ConfigureServices</code> 和 <code>Configure</code> 方法代码迁移到 <code>FurWebCoreStartup.cs</code> 中即可，而 <code>Startup.cs</code> 中两个方法留空即可。</p></div></div><p>非常简单吧。我们后续创建任何 <code>MVC</code>，<code>RazorPages</code>，<code>Blazor</code> 项目只需要添加 <code>Fur.Web.Core</code> 引用和调用 <code>Inject()</code> 即可。</p><h2><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_2cZh" id="37-反馈与建议"></a>3.7 反馈与建议<a aria-hidden="true" tabindex="-1" class="hash-link" href="#37-反馈与建议" title="Direct link to heading">#</a></h2><div class="admonition admonition-note alert alert--secondary"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>与我们交流</h5></div><div class="admonition-content"><p>给 Fur 提 <a href="https://gitee.com/monksoul/Fur/issues/new?issue" target="_blank" rel="noopener noreferrer">Issue</a>。</p></div></div></div></article><div class="margin-vert--xl"><div class="row"><div class="col"><a href="https://gitee.com/monksoul/Fur/tree/main/handbook/docs/appstartup.mdx" target="_blank" rel="noreferrer noopener"><svg fill="currentColor" height="1.2em" width="1.2em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 40 40" style="margin-right:0.3em;vertical-align:sub"><g><path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"></path></g></svg>Edit this page</a></div></div></div><div class="margin-vert--lg"><nav class="pagination-nav" aria-label="Blog list page navigation"><div class="pagination-nav__item"><a class="pagination-nav__link" href="/docs/get-start"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">« 2. 一分钟入门</div></a></div><div class="pagination-nav__item pagination-nav__item--next"><a class="pagination-nav__link" href="/docs/configuration"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">4.1 配置 »</div></a></div></nav></div></div></div><div class="col col--3"><div class="tableOfContents_3SO_"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#31-startup-类" class="table-of-contents__link">3.1 <code>Startup</code> 类</a><ul><li><a href="#311-startup-两个重要方法" class="table-of-contents__link">3.1.1 <code>Startup</code> 两个重要方法</a></li></ul></li><li><a href="#32-appstartup" class="table-of-contents__link">3.2 <code>AppStartup</code></a><ul><li><a href="#321-如何配置-appstartup" class="table-of-contents__link">3.2.1 如何配置 <code>AppStartup</code></a></li><li><a href="#322-appstartup-约定" class="table-of-contents__link">3.2.2 <code>AppStartup</code> 约定</a></li><li><a href="#323-appstartup-配置顺序" class="table-of-contents__link">3.2.3 <code>AppStartup</code> 配置顺序</a></li><li><a href="#324-appstartup-方法调用顺序" class="table-of-contents__link">3.2.4 <code>AppStartup</code> 方法调用顺序</a></li></ul></li><li><a href="#33-框架默认-appstartup-实现" class="table-of-contents__link">3.3 框架默认 <code>AppStartup</code> 实现</a></li><li><a href="#34-startup-配置最佳实践" class="table-of-contents__link">3.4 <code>Startup</code> 配置最佳实践</a></li><li><a href="#35-关于-appsettingsjson" class="table-of-contents__link">3.5 关于 <code>appsettings.json</code></a></li><li><a href="#36-神奇的-inject" class="table-of-contents__link">3.6 神奇的 <code>Inject()</code></a></li><li><a href="#37-反馈与建议" class="table-of-contents__link">3.7 反馈与建议</a></li></ul></div></div></div></div></main></div></div><footer class="footer footer--dark"><div class="container"><div class="row footer__links"><div class="col footer__col"><h4 class="footer__title">文档</h4><ul class="footer__items"><li class="footer__item"><a class="footer__link-item" href="/docs/get-start">入门</a></li><li class="footer__item"><a class="footer__link-item" href="/docs">指南</a></li></ul></div><div class="col footer__col"><h4 class="footer__title">社区</h4><ul class="footer__items"><li class="footer__item"><a href="https://gitee.com/monksoul/Fur/issues" target="_blank" rel="noopener noreferrer" class="footer__link-item">讨论</a></li><li class="footer__item"><a href="https://gitee.com/monksoul/Fur/board" target="_blank" rel="noopener noreferrer" class="footer__link-item">看板</a></li></ul></div><div class="col footer__col"><h4 class="footer__title">更多</h4><ul class="footer__items"><li class="footer__item"><a class="footer__link-item" href="/blog">博客</a></li><li class="footer__item"><a href="https://gitee.com/monksoul/Fur" target="_blank" rel="noopener noreferrer" class="footer__link-item">仓库</a></li></ul></div></div><div class="text--center"><div>Copyright © 2020 Fur, Baiqian Co.,Ltd.</div></div></div></footer></div>
<script src="/styles.8352e18a.js"></script>
<script src="/runtime~main.98e14d7d.js"></script>
<script src="/main.04e1b7d6.js"></script>
<script src="/1.72c59440.js"></script>
<script src="/2.a2e0b0a9.js"></script>
<script src="/3.054f69af.js"></script>
<script src="/1be78505.da78ff7d.js"></script>
<script src="/85.0018927c.js"></script>
<script src="/f976f453.e1be0e0e.js"></script>
<script src="/17896441.9aece880.js"></script>
<script src="/5ce0ebbd.9ae366a6.js"></script>
</body>
</html>